OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 __ jmp(&try_allocate, Label::kNear); | 1029 __ jmp(&try_allocate, Label::kNear); |
1030 | 1030 |
1031 // We have an adaptor frame. Patch the parameters pointer. | 1031 // We have an adaptor frame. Patch the parameters pointer. |
1032 __ bind(&adaptor_frame); | 1032 __ bind(&adaptor_frame); |
1033 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1033 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1034 __ lea(edx, Operand(edx, ecx, times_2, | 1034 __ lea(edx, Operand(edx, ecx, times_2, |
1035 StandardFrameConstants::kCallerSPOffset)); | 1035 StandardFrameConstants::kCallerSPOffset)); |
1036 __ mov(Operand(esp, 2 * kPointerSize), edx); | 1036 __ mov(Operand(esp, 2 * kPointerSize), edx); |
1037 | 1037 |
1038 // ebx = parameter count (tagged) | 1038 // ebx = parameter count (tagged) |
1039 // ecx = argument count (smi-tagged) | 1039 // ecx = argument count (tagged) |
1040 // esp[4] = parameter count (tagged) | 1040 // esp[4] = parameter count (tagged) |
1041 // esp[8] = address of receiver argument | 1041 // esp[8] = address of receiver argument |
1042 // Compute the mapped parameter count = min(ebx, ecx) in ebx. | 1042 // Compute the mapped parameter count = min(ebx, ecx) in ebx. |
1043 __ cmp(ebx, ecx); | 1043 __ cmp(ebx, ecx); |
1044 __ j(less_equal, &try_allocate, Label::kNear); | 1044 __ j(less_equal, &try_allocate, Label::kNear); |
1045 __ mov(ebx, ecx); | 1045 __ mov(ebx, ecx); |
1046 | 1046 |
1047 __ bind(&try_allocate); | 1047 __ bind(&try_allocate); |
1048 | 1048 |
1049 // Save mapped parameter count. | 1049 // Save mapped parameter count. |
(...skipping 12 matching lines...) Expand all Loading... |
1062 // 2. Backing store. | 1062 // 2. Backing store. |
1063 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); | 1063 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); |
1064 | 1064 |
1065 // 3. Arguments object. | 1065 // 3. Arguments object. |
1066 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize)); | 1066 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize)); |
1067 | 1067 |
1068 // Do the allocation of all three objects in one go. | 1068 // Do the allocation of all three objects in one go. |
1069 __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT); | 1069 __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT); |
1070 | 1070 |
1071 // eax = address of new object(s) (tagged) | 1071 // eax = address of new object(s) (tagged) |
1072 // ecx = argument count (smi-tagged) | 1072 // ecx = argument count (tagged) |
1073 // esp[0] = mapped parameter count (tagged) | 1073 // esp[0] = mapped parameter count (tagged) |
1074 // esp[8] = parameter count (tagged) | 1074 // esp[8] = parameter count (tagged) |
1075 // esp[12] = address of receiver argument | 1075 // esp[12] = address of receiver argument |
1076 // Get the arguments map from the current native context into edi. | 1076 // Get the arguments boilerplate from the current native context into edi. |
1077 Label has_mapped_parameters, instantiate; | 1077 Label has_mapped_parameters, copy; |
1078 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 1078 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
1079 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); | 1079 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); |
1080 __ mov(ebx, Operand(esp, 0 * kPointerSize)); | 1080 __ mov(ebx, Operand(esp, 0 * kPointerSize)); |
1081 __ test(ebx, ebx); | 1081 __ test(ebx, ebx); |
1082 __ j(not_zero, &has_mapped_parameters, Label::kNear); | 1082 __ j(not_zero, &has_mapped_parameters, Label::kNear); |
1083 __ mov( | 1083 __ mov(edi, Operand(edi, |
1084 edi, | 1084 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX))); |
1085 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX))); | 1085 __ jmp(©, Label::kNear); |
1086 __ jmp(&instantiate, Label::kNear); | |
1087 | 1086 |
1088 __ bind(&has_mapped_parameters); | 1087 __ bind(&has_mapped_parameters); |
1089 __ mov( | 1088 __ mov(edi, Operand(edi, |
1090 edi, | 1089 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX))); |
1091 Operand(edi, Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX))); | 1090 __ bind(©); |
1092 __ bind(&instantiate); | |
1093 | 1091 |
1094 // eax = address of new object (tagged) | 1092 // eax = address of new object (tagged) |
1095 // ebx = mapped parameter count (tagged) | 1093 // ebx = mapped parameter count (tagged) |
1096 // ecx = argument count (smi-tagged) | 1094 // ecx = argument count (tagged) |
1097 // edi = address of arguments map (tagged) | 1095 // edi = address of boilerplate object (tagged) |
1098 // esp[0] = mapped parameter count (tagged) | 1096 // esp[0] = mapped parameter count (tagged) |
1099 // esp[8] = parameter count (tagged) | 1097 // esp[8] = parameter count (tagged) |
1100 // esp[12] = address of receiver argument | 1098 // esp[12] = address of receiver argument |
1101 // Copy the JS object part. | 1099 // Copy the JS object part. |
1102 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); | 1100 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { |
1103 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), | 1101 __ mov(edx, FieldOperand(edi, i)); |
1104 masm->isolate()->factory()->empty_fixed_array()); | 1102 __ mov(FieldOperand(eax, i), edx); |
1105 __ mov(FieldOperand(eax, JSObject::kElementsOffset), | 1103 } |
1106 masm->isolate()->factory()->empty_fixed_array()); | |
1107 | 1104 |
1108 // Set up the callee in-object property. | 1105 // Set up the callee in-object property. |
1109 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | 1106 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); |
1110 __ mov(edx, Operand(esp, 4 * kPointerSize)); | 1107 __ mov(edx, Operand(esp, 4 * kPointerSize)); |
1111 __ AssertNotSmi(edx); | |
1112 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 1108 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
1113 Heap::kArgumentsCalleeIndex * kPointerSize), | 1109 Heap::kArgumentsCalleeIndex * kPointerSize), |
1114 edx); | 1110 edx); |
1115 | 1111 |
1116 // Use the length (smi tagged) and set that as an in-object property too. | 1112 // Use the length (smi tagged) and set that as an in-object property too. |
1117 __ AssertSmi(ecx); | |
1118 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 1113 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
1119 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 1114 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
1120 Heap::kArgumentsLengthIndex * kPointerSize), | 1115 Heap::kArgumentsLengthIndex * kPointerSize), |
1121 ecx); | 1116 ecx); |
1122 | 1117 |
1123 // Set up the elements pointer in the allocated arguments object. | 1118 // Set up the elements pointer in the allocated arguments object. |
1124 // If we allocated a parameter map, edi will point there, otherwise to the | 1119 // If we allocated a parameter map, edi will point there, otherwise to the |
1125 // backing store. | 1120 // backing store. |
1126 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); | 1121 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); |
1127 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); | 1122 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 __ bind(&try_allocate); | 1259 __ bind(&try_allocate); |
1265 __ test(ecx, ecx); | 1260 __ test(ecx, ecx); |
1266 __ j(zero, &add_arguments_object, Label::kNear); | 1261 __ j(zero, &add_arguments_object, Label::kNear); |
1267 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); | 1262 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); |
1268 __ bind(&add_arguments_object); | 1263 __ bind(&add_arguments_object); |
1269 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); | 1264 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); |
1270 | 1265 |
1271 // Do the allocation of both objects in one go. | 1266 // Do the allocation of both objects in one go. |
1272 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); | 1267 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); |
1273 | 1268 |
1274 // Get the arguments map from the current native context. | 1269 // Get the arguments boilerplate from the current native context. |
1275 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 1270 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
1276 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); | 1271 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); |
1277 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); | 1272 const int offset = |
| 1273 Context::SlotOffset(Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX); |
1278 __ mov(edi, Operand(edi, offset)); | 1274 __ mov(edi, Operand(edi, offset)); |
1279 | 1275 |
1280 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); | 1276 // Copy the JS object part. |
1281 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), | 1277 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { |
1282 masm->isolate()->factory()->empty_fixed_array()); | 1278 __ mov(ebx, FieldOperand(edi, i)); |
1283 __ mov(FieldOperand(eax, JSObject::kElementsOffset), | 1279 __ mov(FieldOperand(eax, i), ebx); |
1284 masm->isolate()->factory()->empty_fixed_array()); | 1280 } |
1285 | 1281 |
1286 // Get the length (smi tagged) and set that as an in-object property too. | 1282 // Get the length (smi tagged) and set that as an in-object property too. |
1287 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 1283 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
1288 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 1284 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
1289 __ AssertSmi(ecx); | |
1290 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 1285 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
1291 Heap::kArgumentsLengthIndex * kPointerSize), | 1286 Heap::kArgumentsLengthIndex * kPointerSize), |
1292 ecx); | 1287 ecx); |
1293 | 1288 |
1294 // If there are no actual arguments, we're done. | 1289 // If there are no actual arguments, we're done. |
1295 Label done; | 1290 Label done; |
1296 __ test(ecx, ecx); | 1291 __ test(ecx, ecx); |
1297 __ j(zero, &done, Label::kNear); | 1292 __ j(zero, &done, Label::kNear); |
1298 | 1293 |
1299 // Get the parameters pointer from the stack. | 1294 // Get the parameters pointer from the stack. |
(...skipping 3693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4993 Operand(ebp, 7 * kPointerSize), | 4988 Operand(ebp, 7 * kPointerSize), |
4994 NULL); | 4989 NULL); |
4995 } | 4990 } |
4996 | 4991 |
4997 | 4992 |
4998 #undef __ | 4993 #undef __ |
4999 | 4994 |
5000 } } // namespace v8::internal | 4995 } } // namespace v8::internal |
5001 | 4996 |
5002 #endif // V8_TARGET_ARCH_IA32 | 4997 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |