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 (tagged) | 1039 // ecx = argument count (smi-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 (tagged) | 1072 // ecx = argument count (smi-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 boilerplate from the current native context into edi. | 1076 // Get the arguments map from the current native context into edi. |
1077 Label has_mapped_parameters, copy; | 1077 Label has_mapped_parameters, instantiate; |
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(edi, Operand(edi, | 1083 __ mov( |
1084 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_BOILERPLATE_INDEX))); | 1084 edi, |
1085 __ jmp(©, Label::kNear); | 1085 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX))); |
| 1086 __ jmp(&instantiate, Label::kNear); |
1086 | 1087 |
1087 __ bind(&has_mapped_parameters); | 1088 __ bind(&has_mapped_parameters); |
1088 __ mov(edi, Operand(edi, | 1089 __ mov( |
1089 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX))); | 1090 edi, |
1090 __ bind(©); | 1091 Operand(edi, Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX))); |
| 1092 __ bind(&instantiate); |
1091 | 1093 |
1092 // eax = address of new object (tagged) | 1094 // eax = address of new object (tagged) |
1093 // ebx = mapped parameter count (tagged) | 1095 // ebx = mapped parameter count (tagged) |
1094 // ecx = argument count (tagged) | 1096 // ecx = argument count (smi-tagged) |
1095 // edi = address of boilerplate object (tagged) | 1097 // edi = address of arguments map (tagged) |
1096 // esp[0] = mapped parameter count (tagged) | 1098 // esp[0] = mapped parameter count (tagged) |
1097 // esp[8] = parameter count (tagged) | 1099 // esp[8] = parameter count (tagged) |
1098 // esp[12] = address of receiver argument | 1100 // esp[12] = address of receiver argument |
1099 // Copy the JS object part. | 1101 // Copy the JS object part. |
1100 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 1102 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); |
1101 __ mov(edx, FieldOperand(edi, i)); | 1103 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
1102 __ mov(FieldOperand(eax, i), edx); | 1104 masm->isolate()->factory()->empty_fixed_array()); |
1103 } | 1105 __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
| 1106 masm->isolate()->factory()->empty_fixed_array()); |
1104 | 1107 |
1105 // Set up the callee in-object property. | 1108 // Set up the callee in-object property. |
1106 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | 1109 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); |
1107 __ mov(edx, Operand(esp, 4 * kPointerSize)); | 1110 __ mov(edx, Operand(esp, 4 * kPointerSize)); |
| 1111 __ AssertNotSmi(edx); |
1108 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 1112 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
1109 Heap::kArgumentsCalleeIndex * kPointerSize), | 1113 Heap::kArgumentsCalleeIndex * kPointerSize), |
1110 edx); | 1114 edx); |
1111 | 1115 |
1112 // Use the length (smi tagged) and set that as an in-object property too. | 1116 // Use the length (smi tagged) and set that as an in-object property too. |
| 1117 __ AssertSmi(ecx); |
1113 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 1118 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
1114 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 1119 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
1115 Heap::kArgumentsLengthIndex * kPointerSize), | 1120 Heap::kArgumentsLengthIndex * kPointerSize), |
1116 ecx); | 1121 ecx); |
1117 | 1122 |
1118 // Set up the elements pointer in the allocated arguments object. | 1123 // Set up the elements pointer in the allocated arguments object. |
1119 // If we allocated a parameter map, edi will point there, otherwise to the | 1124 // If we allocated a parameter map, edi will point there, otherwise to the |
1120 // backing store. | 1125 // backing store. |
1121 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); | 1126 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); |
1122 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); | 1127 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 __ bind(&try_allocate); | 1264 __ bind(&try_allocate); |
1260 __ test(ecx, ecx); | 1265 __ test(ecx, ecx); |
1261 __ j(zero, &add_arguments_object, Label::kNear); | 1266 __ j(zero, &add_arguments_object, Label::kNear); |
1262 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); | 1267 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); |
1263 __ bind(&add_arguments_object); | 1268 __ bind(&add_arguments_object); |
1264 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); | 1269 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); |
1265 | 1270 |
1266 // Do the allocation of both objects in one go. | 1271 // Do the allocation of both objects in one go. |
1267 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); | 1272 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); |
1268 | 1273 |
1269 // Get the arguments boilerplate from the current native context. | 1274 // Get the arguments map from the current native context. |
1270 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 1275 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
1271 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); | 1276 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); |
1272 const int offset = | 1277 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); |
1273 Context::SlotOffset(Context::STRICT_ARGUMENTS_BOILERPLATE_INDEX); | |
1274 __ mov(edi, Operand(edi, offset)); | 1278 __ mov(edi, Operand(edi, offset)); |
1275 | 1279 |
1276 // Copy the JS object part. | 1280 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); |
1277 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 1281 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
1278 __ mov(ebx, FieldOperand(edi, i)); | 1282 masm->isolate()->factory()->empty_fixed_array()); |
1279 __ mov(FieldOperand(eax, i), ebx); | 1283 __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
1280 } | 1284 masm->isolate()->factory()->empty_fixed_array()); |
1281 | 1285 |
1282 // Get the length (smi tagged) and set that as an in-object property too. | 1286 // Get the length (smi tagged) and set that as an in-object property too. |
1283 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 1287 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
1284 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 1288 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
| 1289 __ AssertSmi(ecx); |
1285 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 1290 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
1286 Heap::kArgumentsLengthIndex * kPointerSize), | 1291 Heap::kArgumentsLengthIndex * kPointerSize), |
1287 ecx); | 1292 ecx); |
1288 | 1293 |
1289 // If there are no actual arguments, we're done. | 1294 // If there are no actual arguments, we're done. |
1290 Label done; | 1295 Label done; |
1291 __ test(ecx, ecx); | 1296 __ test(ecx, ecx); |
1292 __ j(zero, &done, Label::kNear); | 1297 __ j(zero, &done, Label::kNear); |
1293 | 1298 |
1294 // Get the parameters pointer from the stack. | 1299 // Get the parameters pointer from the stack. |
(...skipping 3693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4988 Operand(ebp, 7 * kPointerSize), | 4993 Operand(ebp, 7 * kPointerSize), |
4989 NULL); | 4994 NULL); |
4990 } | 4995 } |
4991 | 4996 |
4992 | 4997 |
4993 #undef __ | 4998 #undef __ |
4994 | 4999 |
4995 } } // namespace v8::internal | 5000 } } // namespace v8::internal |
4996 | 5001 |
4997 #endif // V8_TARGET_ARCH_IA32 | 5002 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |