| 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 912 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   923 } |   923 } | 
|   924  |   924  | 
|   925  |   925  | 
|   926 // Allocate an empty JSArray. The allocated array is put into the result |   926 // Allocate an empty JSArray. The allocated array is put into the result | 
|   927 // register. If the parameter initial_capacity is larger than zero an elements |   927 // register. If the parameter initial_capacity is larger than zero an elements | 
|   928 // backing store is allocated with this size and filled with the hole values. |   928 // backing store is allocated with this size and filled with the hole values. | 
|   929 // Otherwise the elements backing store is set to the empty FixedArray. |   929 // Otherwise the elements backing store is set to the empty FixedArray. | 
|   930 static void AllocateEmptyJSArray(MacroAssembler* masm, |   930 static void AllocateEmptyJSArray(MacroAssembler* masm, | 
|   931                                  Register array_function, |   931                                  Register array_function, | 
|   932                                  Register result, |   932                                  Register result, | 
|   933                                  Register scratch1, |   933                                  Register type_info_cell, | 
|   934                                  Register scratch2, |   934                                  Register scratch2, | 
|   935                                  Register scratch3, |   935                                  Register scratch3, | 
|   936                                  Label* gc_required) { |   936                                  Label* gc_required) { | 
|   937   const int initial_capacity = JSArray::kPreallocatedArrayElements; |   937   Label with_alloc_info, no_alloc_info, common_init, empty_double; | 
|   938   STATIC_ASSERT(initial_capacity >= 0); |   938   Label no_known_elements_kind, init_js_array; | 
 |   939   Register scratch1 = type_info_cell; | 
|   939  |   940  | 
|   940   __ LoadInitialArrayMap(array_function, scratch2, scratch1, false); |   941   // If no type info cell is provided, then there's no point in tracking | 
 |   942   // site allocation info. | 
 |   943   Handle<Object> undefined_value(masm->isolate()->heap()->undefined_value()); | 
 |   944   __ cmp(type_info_cell, Immediate(undefined_value)); | 
 |   945   __ j(equal, &no_known_elements_kind); | 
|   941  |   946  | 
 |   947   // If there is a type info cell provided, only track information about the | 
 |   948   // allocation site if the no ElementsKind transition has been detected. | 
 |   949   __ mov(scratch3, FieldOperand(type_info_cell, | 
 |   950                                 JSGlobalPropertyCell::kValueOffset)); | 
 |   951   __ JumpIfNotSmi(scratch3, &no_known_elements_kind); | 
 |   952   __ cmp(scratch3, Immediate(Smi::FromInt(GetInitialFastElementsKind()))); | 
 |   953   __ j(equal, &with_alloc_info); | 
 |   954  | 
 |   955   STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 
 |   956   STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 
 |   957   STATIC_ASSERT(FAST_ELEMENTS == 2); | 
 |   958   STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | 
 |   959   __ cmp(scratch3, Immediate(Smi::FromInt(FAST_HOLEY_ELEMENTS))); | 
 |   960   __ j(above, gc_required); | 
 |   961  | 
 |   962   __ LoadInitialArrayMap(array_function, scratch3, scratch2); | 
 |   963   __ jmp(&no_alloc_info); | 
 |   964    | 
|   942   // Allocate the JSArray object together with space for a fixed array with the |   965   // Allocate the JSArray object together with space for a fixed array with the | 
|   943   // requested elements. |   966   // requested elements and an AllocationSiteInfo object to later be able to | 
 |   967   // feed back array transition information to the allocation site. | 
 |   968   __ bind(&with_alloc_info); | 
|   944   int size = JSArray::kSize; |   969   int size = JSArray::kSize; | 
|   945   if (initial_capacity > 0) { |   970   int allocation_info_start = size; | 
|   946     size += FixedArray::SizeFor(initial_capacity); |   971   int elements_offset = size; | 
|   947   } |   972   size += AllocationSiteInfo::kSize; | 
 |   973   elements_offset = size; | 
 |   974   size += FixedArray::SizeFor(JSArray::kPreallocatedArrayElements); | 
|   948   __ AllocateInNewSpace(size, |   975   __ AllocateInNewSpace(size, | 
|   949                         result, |   976                         result, | 
|   950                         scratch2, |   977                         scratch2, | 
|   951                         scratch3, |   978                         scratch3, | 
|   952                         gc_required, |   979                         gc_required, | 
|   953                         TAG_OBJECT); |   980                         TAG_OBJECT);   | 
|   954  |   981    | 
|   955   // Allocated the JSArray. Now initialize the fields except for the elements |   982   // Track information about the allocation site | 
|   956   // array. |   983   __ mov(FieldOperand(result, allocation_info_start), | 
|   957   // result: JSObject |   984          Immediate(Handle<Map>(masm->isolate()->heap()-> | 
|   958   // scratch1: initial map |   985                                allocation_site_info_map()))); | 
|   959   // scratch2: start of next object |   986   __ mov(FieldOperand(result, allocation_info_start + kPointerSize), | 
|   960   __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1); |   987          type_info_cell);  // No write barrier because it's a cell. | 
|   961   Factory* factory = masm->isolate()->factory(); |  | 
|   962   __ mov(FieldOperand(result, JSArray::kPropertiesOffset), |  | 
|   963          factory->empty_fixed_array()); |  | 
|   964   // Field JSArray::kElementsOffset is initialized later. |  | 
|   965   __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0)); |  | 
|   966  |  | 
|   967   // If no storage is requested for the elements array just set the empty |  | 
|   968   // fixed array. |  | 
|   969   if (initial_capacity == 0) { |  | 
|   970     __ mov(FieldOperand(result, JSArray::kElementsOffset), |  | 
|   971            factory->empty_fixed_array()); |  | 
|   972     return; |  | 
|   973   } |  | 
|   974  |   988  | 
|   975   // Calculate the location of the elements array and set elements array member |   989   // Calculate the location of the elements array and set elements array member | 
|   976   // of the JSArray. |   990   // of the JSArray. | 
|   977   // result: JSObject |   991   // result: JSArray | 
|   978   // scratch2: start of next object |   992   __ LoadInitialArrayMap(array_function, GetInitialFastElementsKind(), scratch2)
      ; | 
|   979   __ lea(scratch1, Operand(result, JSArray::kSize)); |   993   __ lea(scratch1, Operand(result, elements_offset)); | 
|   980   __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1); |   994   __ jmp(&common_init); | 
|   981  |   995  | 
 |   996   __ bind(&no_known_elements_kind); | 
 |   997   __ LoadInitialArrayMap(array_function, GetInitialFastElementsKind(), scratch2)
      ; | 
 |   998    | 
 |   999   // Allocate the JSArray object together with space for a fixed array with the | 
 |  1000   // requested elements. | 
 |  1001   __ bind(&no_alloc_info); | 
 |  1002   size = JSArray::kSize; | 
 |  1003   elements_offset = size; | 
 |  1004   size += FixedArray::SizeFor(JSArray::kPreallocatedArrayElements); | 
 |  1005   __ AllocateInNewSpace(size, | 
 |  1006                         result, | 
 |  1007                         scratch1, | 
 |  1008                         scratch3, | 
 |  1009                         gc_required, | 
 |  1010                         TAG_OBJECT); | 
 |  1011   // Calculate the location of the elements array and set elements array member | 
 |  1012   // of the JSArray. | 
 |  1013   // result: JSArray | 
 |  1014   __ lea(scratch1, Operand(result, elements_offset)); | 
 |  1015    | 
 |  1016   __ bind(&common_init); | 
|   982   // Initialize the FixedArray and fill it with holes. FixedArray length is |  1017   // Initialize the FixedArray and fill it with holes. FixedArray length is | 
|   983   // stored as a smi. |  1018   // stored as a smi. | 
|   984   // result: JSObject |  1019   // result: JSObject | 
|   985   // scratch1: elements array |  1020   // scratch1: elements array | 
|   986   // scratch2: start of next object |  1021   Factory* factory = masm->isolate()->factory(); | 
|   987   __ mov(FieldOperand(scratch1, FixedArray::kMapOffset), |  1022   __ mov(FieldOperand(scratch1, FixedArray::kMapOffset), | 
|   988          factory->fixed_array_map()); |  1023          factory->fixed_array_map()); | 
|   989   __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset), |  1024   __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset), | 
|   990          Immediate(Smi::FromInt(initial_capacity))); |  1025          Immediate(Smi::FromInt(JSArray::kPreallocatedArrayElements))); | 
|   991  |  1026  | 
|   992   // Fill the FixedArray with the hole value. Inline the code if short. |  1027   // Fill the FixedArray with the hole value. Inline the code if short. | 
|   993   // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. |  1028   // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. | 
|   994   static const int kLoopUnfoldLimit = 4; |  1029   static const int kLoopUnfoldLimit = 4; | 
|   995   if (initial_capacity <= kLoopUnfoldLimit) { |  1030   if (JSArray::kPreallocatedArrayElements <= kLoopUnfoldLimit) { | 
|   996     // Use a scratch register here to have only one reloc info when unfolding |  1031     // Use a scratch register here to have only one reloc info when unfolding | 
|   997     // the loop. |  1032     // the loop. | 
|   998     __ mov(scratch3, factory->the_hole_value()); |  1033     __ mov(scratch3, factory->the_hole_value()); | 
|   999     for (int i = 0; i < initial_capacity; i++) { |  1034     for (int i = 0; i < JSArray::kPreallocatedArrayElements; i++) { | 
|  1000       __ mov(FieldOperand(scratch1, |  1035       __ mov(FieldOperand(scratch1, | 
|  1001                           FixedArray::kHeaderSize + i * kPointerSize), |  1036                           FixedArray::kHeaderSize + i * kPointerSize), | 
|  1002              scratch3); |  1037              scratch3); | 
|  1003     } |  1038     } | 
|  1004   } else { |  1039   } else { | 
|  1005     Label loop, entry; |  1040     Label loop, entry; | 
|  1006     __ mov(scratch2, Immediate(initial_capacity)); |  1041     __ mov(scratch3, Immediate(JSArray::kPreallocatedArrayElements)); | 
|  1007     __ jmp(&entry); |  1042     __ jmp(&entry); | 
|  1008     __ bind(&loop); |  1043     __ bind(&loop); | 
|  1009     __ mov(FieldOperand(scratch1, |  1044     __ mov(FieldOperand(scratch1, | 
|  1010                         scratch2, |  1045                         scratch3, | 
|  1011                         times_pointer_size, |  1046                         times_pointer_size, | 
|  1012                         FixedArray::kHeaderSize), |  1047                         FixedArray::kHeaderSize), | 
|  1013            factory->the_hole_value()); |  1048            factory->the_hole_value()); | 
|  1014     __ bind(&entry); |  1049     __ bind(&entry); | 
|  1015     __ dec(scratch2); |  1050     __ dec(scratch3); | 
|  1016     __ j(not_sign, &loop); |  1051     __ j(not_sign, &loop); | 
|  1017   } |  1052   } | 
 |  1053  | 
 |  1054   __ bind(&init_js_array); | 
 |  1055   // Initialize the fields of the JSArray | 
 |  1056   // result: JSArray | 
 |  1057   // scratch1: elements array | 
 |  1058   // scratch2: map for Array | 
 |  1059   __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1); | 
 |  1060   __ mov(FieldOperand(result, JSObject::kMapOffset), scratch2); | 
 |  1061   __ mov(FieldOperand(result, JSArray::kPropertiesOffset), | 
 |  1062          factory->empty_fixed_array()); | 
 |  1063   __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0)); | 
|  1018 } |  1064 } | 
|  1019  |  1065  | 
|  1020  |  1066  | 
|  1021 // Allocate a JSArray with the number of elements stored in a register. The |  1067 // Allocate a JSArray with the number of elements stored in a register. The | 
|  1022 // register array_function holds the built-in Array function and the register |  1068 // register array_function holds the built-in Array function and the register | 
|  1023 // array_size holds the size of the array as a smi. The allocated array is put |  1069 // array_size holds the size of the array as a smi. The allocated array is put | 
|  1024 // into the result register and beginning and end of the FixedArray elements |  1070 // into the result register and beginning and end of the FixedArray elements | 
|  1025 // storage is put into registers elements_array and elements_array_end  (see |  1071 // storage is put into registers elements_array and elements_array_end  (see | 
|  1026 // below for when that is not the case). If the parameter fill_with_holes is |  1072 // below for when that is not the case). If the parameter fill_with_holes is | 
|  1027 // true the allocated elements backing store is filled with the hole values |  1073 // true the allocated elements backing store is filled with the hole values | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  1039   ASSERT(scratch.is(edi));  // rep stos destination |  1085   ASSERT(scratch.is(edi));  // rep stos destination | 
|  1040   ASSERT(!fill_with_hole || array_size.is(ecx));  // rep stos count |  1086   ASSERT(!fill_with_hole || array_size.is(ecx));  // rep stos count | 
|  1041   ASSERT(!fill_with_hole || !result.is(eax));  // result is never eax |  1087   ASSERT(!fill_with_hole || !result.is(eax));  // result is never eax | 
|  1042  |  1088  | 
|  1043   __ LoadInitialArrayMap(array_function, scratch, |  1089   __ LoadInitialArrayMap(array_function, scratch, | 
|  1044                          elements_array, fill_with_hole); |  1090                          elements_array, fill_with_hole); | 
|  1045  |  1091  | 
|  1046   // Allocate the JSArray object together with space for a FixedArray with the |  1092   // Allocate the JSArray object together with space for a FixedArray with the | 
|  1047   // requested elements. |  1093   // requested elements. | 
|  1048   STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |  1094   STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 
|  1049   __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize, |  1095  | 
 |  1096   int fixed_size = JSArray::kSize + FixedArray::kHeaderSize + | 
 |  1097       AllocationSiteInfo::kSize; | 
 |  1098   __ AllocateInNewSpace(fixed_size, | 
|  1050                         times_half_pointer_size,  // array_size is a smi. |  1099                         times_half_pointer_size,  // array_size is a smi. | 
|  1051                         array_size, |  1100                         array_size, | 
|  1052                         result, |  1101                         result, | 
|  1053                         elements_array_end, |  1102                         elements_array_end, | 
|  1054                         scratch, |  1103                         scratch, | 
|  1055                         gc_required, |  1104                         gc_required, | 
|  1056                         TAG_OBJECT); |  1105                         TAG_OBJECT); | 
 |  1106   __ sub(elements_array_end, Immediate(AllocationSiteInfo::kSize)); | 
|  1057  |  1107  | 
|  1058   // Allocated the JSArray. Now initialize the fields except for the elements |  1108   // Allocated the JSArray. Now initialize the fields except for the elements | 
|  1059   // array. |  1109   // array. | 
|  1060   // result: JSObject |  1110   // result: JSObject | 
|  1061   // elements_array: initial map |  1111   // elements_array: initial map | 
|  1062   // elements_array_end: start of next object |  1112   // elements_array_end: start of next object | 
|  1063   // array_size: size of array (smi) |  1113   // array_size: size of array (smi) | 
|  1064   __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array); |  1114   __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array); | 
|  1065   Factory* factory = masm->isolate()->factory(); |  1115   Factory* factory = masm->isolate()->factory(); | 
|  1066   __ mov(elements_array, factory->empty_fixed_array()); |  1116   __ mov(elements_array, factory->empty_fixed_array()); | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1104     __ j(below, &loop);  // Note: ecx > 0. |  1154     __ j(below, &loop);  // Note: ecx > 0. | 
|  1105     __ rep_stos(); |  1155     __ rep_stos(); | 
|  1106     __ jmp(&done); |  1156     __ jmp(&done); | 
|  1107     __ bind(&loop); |  1157     __ bind(&loop); | 
|  1108     __ stos(); |  1158     __ stos(); | 
|  1109     __ bind(&entry); |  1159     __ bind(&entry); | 
|  1110     __ cmp(edi, elements_array_end); |  1160     __ cmp(edi, elements_array_end); | 
|  1111     __ j(below, &loop); |  1161     __ j(below, &loop); | 
|  1112     __ bind(&done); |  1162     __ bind(&done); | 
|  1113   } |  1163   } | 
 |  1164  | 
 |  1165   // Track information about the allocation site | 
 |  1166   __ mov(Operand(elements_array_end, 0), | 
 |  1167          Immediate(Handle<Map>(masm->isolate()->heap()-> | 
 |  1168                                allocation_site_info_map()))); | 
 |  1169   __ mov(Operand(elements_array_end, kPointerSize), | 
 |  1170          Immediate(Handle<HeapObject>(masm->isolate()->heap()->null_value()))); | 
|  1114 } |  1171 } | 
|  1115  |  1172  | 
|  1116  |  1173  | 
|  1117 // Create a new array for the built-in Array function. This function allocates |  1174 // Create a new array for the built-in Array function. This function allocates | 
|  1118 // the JSArray object and the FixedArray elements array and initializes these. |  1175 // the JSArray object and the FixedArray elements array and initializes these. | 
|  1119 // If the Array cannot be constructed in native code the runtime is called. This |  1176 // If the Array cannot be constructed in native code the runtime is called. This | 
|  1120 // function assumes the following state: |  1177 // function assumes the following state: | 
|  1121 //   edi: constructor (built-in Array function) |  1178 //   edi: constructor (built-in Array function) | 
|  1122 //   eax: argc |  1179 //   eax: argc | 
 |  1180 //   ebx: cell containing type feedback cell for Array's ElementsKind | 
|  1123 //   esp[0]: return address |  1181 //   esp[0]: return address | 
|  1124 //   esp[4]: last argument |  1182 //   esp[4]: last argument | 
|  1125 // This function is used for both construct and normal calls of Array. Whether |  1183 // This function is used for both construct and normal calls of Array. Whether | 
|  1126 // it is a construct call or not is indicated by the construct_call parameter. |  1184 // it is a construct call or not is indicated by the construct_call parameter. | 
|  1127 // The only difference between handling a construct call and a normal call is |  1185 // The only difference between handling a construct call and a normal call is | 
|  1128 // that for a construct call the constructor function in edi needs to be |  1186 // that for a construct call the constructor function in edi needs to be | 
|  1129 // preserved for entering the generic code. In both cases argc in eax needs to |  1187 // preserved for entering the generic code. In both cases argc in eax needs to | 
|  1130 // be preserved. |  1188 // be preserved. | 
|  1131 static void ArrayNativeCode(MacroAssembler* masm, |  1189 static void ArrayNativeCode(MacroAssembler* masm, | 
|  1132                             bool construct_call, |  1190                             bool construct_call, | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|  1148   __ test(eax, eax); |  1206   __ test(eax, eax); | 
|  1149   __ j(not_zero, &argc_one_or_more); |  1207   __ j(not_zero, &argc_one_or_more); | 
|  1150  |  1208  | 
|  1151   __ bind(&empty_array); |  1209   __ bind(&empty_array); | 
|  1152   // Handle construction of an empty array. |  1210   // Handle construction of an empty array. | 
|  1153   AllocateEmptyJSArray(masm, |  1211   AllocateEmptyJSArray(masm, | 
|  1154                        edi, |  1212                        edi, | 
|  1155                        eax, |  1213                        eax, | 
|  1156                        ebx, |  1214                        ebx, | 
|  1157                        ecx, |  1215                        ecx, | 
|  1158                        edi, |  1216                        edx, | 
|  1159                        &prepare_generic_code_call); |  1217                        &prepare_generic_code_call); | 
|  1160   __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1); |  1218   __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1); | 
|  1161   __ pop(ebx); |  1219   __ pop(ebx); | 
|  1162   if (construct_call) { |  1220   if (construct_call) { | 
|  1163     __ pop(edi); |  1221     __ pop(edi); | 
|  1164   } |  1222   } | 
|  1165   __ ret(kPointerSize); |  1223   __ ret(kPointerSize); | 
|  1166  |  1224  | 
|  1167   // Check for one argument. Bail out if argument is not smi or if it is |  1225   // Check for one argument. Bail out if argument is not smi or if it is | 
|  1168   // negative. |  1226   // negative. | 
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1354   //  -- esp[0] : return address |  1412   //  -- esp[0] : return address | 
|  1355   //  -- esp[4] : last argument |  1413   //  -- esp[4] : last argument | 
|  1356   // ----------------------------------- |  1414   // ----------------------------------- | 
|  1357   Label generic_array_code; |  1415   Label generic_array_code; | 
|  1358  |  1416  | 
|  1359   // Get the InternalArray function. |  1417   // Get the InternalArray function. | 
|  1360   __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); |  1418   __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); | 
|  1361  |  1419  | 
|  1362   if (FLAG_debug_code) { |  1420   if (FLAG_debug_code) { | 
|  1363     // Initial map for the builtin InternalArray function should be a map. |  1421     // Initial map for the builtin InternalArray function should be a map. | 
|  1364     __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |  1422     __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 
|  1365     // Will both indicate a NULL and a Smi. |  1423     // Will both indicate a NULL and a Smi. | 
|  1366     __ test(ebx, Immediate(kSmiTagMask)); |  1424     __ test(ecx, Immediate(kSmiTagMask)); | 
|  1367     __ Assert(not_zero, "Unexpected initial map for InternalArray function"); |  1425     __ Assert(not_zero, "Unexpected initial map for InternalArray function"); | 
|  1368     __ CmpObjectType(ebx, MAP_TYPE, ecx); |  1426     __ CmpObjectType(ecx, MAP_TYPE, ecx); | 
|  1369     __ Assert(equal, "Unexpected initial map for InternalArray function"); |  1427     __ Assert(equal, "Unexpected initial map for InternalArray function"); | 
|  1370   } |  1428   } | 
|  1371  |  1429  | 
 |  1430   // No type feedback cell is available | 
 |  1431   Handle<Object> undefined_sentinel(masm->isolate()->heap()->undefined_value()); | 
 |  1432   __ mov(ebx, Immediate(undefined_sentinel)); | 
 |  1433  | 
|  1372   // Run the native code for the InternalArray function called as a normal |  1434   // Run the native code for the InternalArray function called as a normal | 
|  1373   // function. |  1435   // function. | 
|  1374   ArrayNativeCode(masm, false, &generic_array_code); |  1436   ArrayNativeCode(masm, false, &generic_array_code); | 
|  1375  |  1437  | 
|  1376   // Jump to the generic internal array code in case the specialized code cannot |  1438   // Jump to the generic internal array code in case the specialized code cannot | 
|  1377   // handle the construction. |  1439   // handle the construction. | 
|  1378   __ bind(&generic_array_code); |  1440   __ bind(&generic_array_code); | 
|  1379   Handle<Code> array_code = |  1441   Handle<Code> array_code = | 
|  1380       masm->isolate()->builtins()->InternalArrayCodeGeneric(); |  1442       masm->isolate()->builtins()->InternalArrayCodeGeneric(); | 
|  1381   __ jmp(array_code, RelocInfo::CODE_TARGET); |  1443   __ jmp(array_code, RelocInfo::CODE_TARGET); | 
|  1382 } |  1444 } | 
|  1383  |  1445  | 
|  1384  |  1446  | 
|  1385 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { |  1447 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { | 
|  1386   // ----------- S t a t e ------------- |  1448   // ----------- S t a t e ------------- | 
|  1387   //  -- eax : argc |  1449   //  -- eax : argc | 
|  1388   //  -- esp[0] : return address |  1450   //  -- esp[0] : return address | 
|  1389   //  -- esp[4] : last argument |  1451   //  -- esp[4] : last argument | 
|  1390   // ----------------------------------- |  1452   // ----------------------------------- | 
|  1391   Label generic_array_code; |  1453   Label generic_array_code; | 
|  1392  |  1454  | 
|  1393   // Get the Array function. |  1455   // Get the Array function. | 
|  1394   __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); |  1456   __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); | 
|  1395  |  1457  | 
|  1396   if (FLAG_debug_code) { |  1458   if (FLAG_debug_code) { | 
|  1397     // Initial map for the builtin Array function should be a map. |  1459     // Initial map for the builtin Array function should be a map. | 
|  1398     __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |  1460     __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 
|  1399     // Will both indicate a NULL and a Smi. |  1461     // Will both indicate a NULL and a Smi. | 
|  1400     __ test(ebx, Immediate(kSmiTagMask)); |  1462     __ test(ecx, Immediate(kSmiTagMask)); | 
|  1401     __ Assert(not_zero, "Unexpected initial map for Array function"); |  1463     __ Assert(not_zero, "Unexpected initial map for Array function"); | 
|  1402     __ CmpObjectType(ebx, MAP_TYPE, ecx); |  1464     __ CmpObjectType(ecx, MAP_TYPE, ecx); | 
|  1403     __ Assert(equal, "Unexpected initial map for Array function"); |  1465     __ Assert(equal, "Unexpected initial map for Array function"); | 
|  1404   } |  1466   } | 
|  1405  |  1467  | 
 |  1468   // No type feedback cell is available | 
 |  1469   Handle<Object> undefined_sentinel(masm->isolate()->heap()->undefined_value()); | 
 |  1470   __ mov(ebx, Immediate(undefined_sentinel)); | 
 |  1471    | 
|  1406   // Run the native code for the Array function called as a normal function. |  1472   // Run the native code for the Array function called as a normal function. | 
|  1407   ArrayNativeCode(masm, false, &generic_array_code); |  1473   ArrayNativeCode(masm, false, &generic_array_code); | 
|  1408  |  1474  | 
|  1409   // Jump to the generic array code in case the specialized code cannot handle |  1475   // Jump to the generic array code in case the specialized code cannot handle | 
|  1410   // the construction. |  1476   // the construction. | 
|  1411   __ bind(&generic_array_code); |  1477   __ bind(&generic_array_code); | 
|  1412   Handle<Code> array_code = |  1478   Handle<Code> array_code = | 
|  1413       masm->isolate()->builtins()->ArrayCodeGeneric(); |  1479       masm->isolate()->builtins()->ArrayCodeGeneric(); | 
|  1414   __ jmp(array_code, RelocInfo::CODE_TARGET); |  1480   __ jmp(array_code, RelocInfo::CODE_TARGET); | 
|  1415 } |  1481 } | 
|  1416  |  1482  | 
|  1417  |  1483  | 
|  1418 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) { |  1484 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) { | 
|  1419   // ----------- S t a t e ------------- |  1485   // ----------- S t a t e ------------- | 
|  1420   //  -- eax : argc |  1486   //  -- eax : argc | 
|  1421   //  -- edi : constructor |  1487   //  -- edi : constructor | 
|  1422   //  -- esp[0] : return address |  1488   //  -- esp[0] : return address | 
|  1423   //  -- esp[4] : last argument |  1489   //  -- esp[4] : last argument | 
|  1424   // ----------------------------------- |  1490   // ----------------------------------- | 
|  1425   Label generic_constructor; |  1491   Label generic_constructor; | 
|  1426  |  1492  | 
|  1427   if (FLAG_debug_code) { |  1493   if (FLAG_debug_code) { | 
|  1428     // The array construct code is only set for the global and natives |  1494     // The array construct code is only set for the global and natives | 
|  1429     // builtin Array functions which always have maps. |  1495     // builtin Array functions which always have maps. | 
|  1430  |  1496  | 
|  1431     // Initial map for the builtin Array function should be a map. |  1497     // Initial map for the builtin Array function should be a map. | 
|  1432     __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |  1498     __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 
|  1433     // Will both indicate a NULL and a Smi. |  1499     // Will both indicate a NULL and a Smi. | 
|  1434     __ test(ebx, Immediate(kSmiTagMask)); |  1500     __ test(ecx, Immediate(kSmiTagMask)); | 
|  1435     __ Assert(not_zero, "Unexpected initial map for Array function"); |  1501     __ Assert(not_zero, "Unexpected initial map for Array function"); | 
|  1436     __ CmpObjectType(ebx, MAP_TYPE, ecx); |  1502     __ CmpObjectType(ecx, MAP_TYPE, ecx); | 
|  1437     __ Assert(equal, "Unexpected initial map for Array function"); |  1503     __ Assert(equal, "Unexpected initial map for Array function"); | 
|  1438   } |  1504   } | 
|  1439  |  1505  | 
|  1440   // Run the native code for the Array function called as constructor. |  1506   // Run the native code for the Array function called as constructor. | 
|  1441   ArrayNativeCode(masm, true, &generic_constructor); |  1507   ArrayNativeCode(masm, true, &generic_constructor); | 
|  1442  |  1508  | 
|  1443   // Jump to the generic construct code in case the specialized code cannot |  1509   // Jump to the generic construct code in case the specialized code cannot | 
|  1444   // handle the construction. |  1510   // handle the construction. | 
|  1445   __ bind(&generic_constructor); |  1511   __ bind(&generic_constructor); | 
|  1446   Handle<Code> generic_construct_stub = |  1512   Handle<Code> generic_construct_stub = | 
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1767   Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |  1833   Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 
|  1768   generator.Generate(); |  1834   generator.Generate(); | 
|  1769 } |  1835 } | 
|  1770  |  1836  | 
|  1771  |  1837  | 
|  1772 #undef __ |  1838 #undef __ | 
|  1773 } |  1839 } | 
|  1774 }  // namespace v8::internal |  1840 }  // namespace v8::internal | 
|  1775  |  1841  | 
|  1776 #endif  // V8_TARGET_ARCH_IA32 |  1842 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |