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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 73 |
74 __ IncrementCounter(counters->fast_new_closure_total(), 1); | 74 __ IncrementCounter(counters->fast_new_closure_total(), 1); |
75 | 75 |
76 // Get the function info from the stack. | 76 // Get the function info from the stack. |
77 __ mov(edx, Operand(esp, 1 * kPointerSize)); | 77 __ mov(edx, Operand(esp, 1 * kPointerSize)); |
78 | 78 |
79 int map_index = (language_mode_ == CLASSIC_MODE) | 79 int map_index = (language_mode_ == CLASSIC_MODE) |
80 ? Context::FUNCTION_MAP_INDEX | 80 ? Context::FUNCTION_MAP_INDEX |
81 : Context::STRICT_MODE_FUNCTION_MAP_INDEX; | 81 : Context::STRICT_MODE_FUNCTION_MAP_INDEX; |
82 | 82 |
83 // Compute the function map in the current global context and set that | 83 // Compute the function map in the current native context and set that |
84 // as the map of the allocated object. | 84 // as the map of the allocated object. |
85 __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 85 __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
86 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset)); | 86 __ mov(ecx, FieldOperand(ecx, GlobalObject::kNativeContextOffset)); |
87 __ mov(ebx, Operand(ecx, Context::SlotOffset(map_index))); | 87 __ mov(ebx, Operand(ecx, Context::SlotOffset(map_index))); |
88 __ mov(FieldOperand(eax, JSObject::kMapOffset), ebx); | 88 __ mov(FieldOperand(eax, JSObject::kMapOffset), ebx); |
89 | 89 |
90 // Initialize the rest of the function. We don't have to update the | 90 // Initialize the rest of the function. We don't have to update the |
91 // write barrier because the allocated object is in new space. | 91 // write barrier because the allocated object is in new space. |
92 Factory* factory = masm->isolate()->factory(); | 92 Factory* factory = masm->isolate()->factory(); |
93 __ mov(ebx, Immediate(factory->empty_fixed_array())); | 93 __ mov(ebx, Immediate(factory->empty_fixed_array())); |
94 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ebx); | 94 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ebx); |
95 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx); | 95 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx); |
96 __ mov(FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset), | 96 __ mov(FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset), |
(...skipping 19 matching lines...) Expand all Loading... |
116 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); | 116 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); |
117 __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx); | 117 __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx); |
118 | 118 |
119 // Return and remove the on-stack parameter. | 119 // Return and remove the on-stack parameter. |
120 __ ret(1 * kPointerSize); | 120 __ ret(1 * kPointerSize); |
121 | 121 |
122 __ bind(&check_optimized); | 122 __ bind(&check_optimized); |
123 | 123 |
124 __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1); | 124 __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1); |
125 | 125 |
126 // ecx holds global context, ebx points to fixed array of 3-element entries | 126 // ecx holds native context, ebx points to fixed array of 3-element entries |
127 // (global context, optimized code, literals). | 127 // (native context, optimized code, literals). |
128 // Map must never be empty, so check the first elements. | 128 // Map must never be empty, so check the first elements. |
129 Label install_optimized; | 129 Label install_optimized; |
130 // Speculatively move code object into edx. | 130 // Speculatively move code object into edx. |
131 __ mov(edx, FieldOperand(ebx, FixedArray::kHeaderSize + kPointerSize)); | 131 __ mov(edx, FieldOperand(ebx, FixedArray::kHeaderSize + kPointerSize)); |
132 __ cmp(ecx, FieldOperand(ebx, FixedArray::kHeaderSize)); | 132 __ cmp(ecx, FieldOperand(ebx, FixedArray::kHeaderSize)); |
133 __ j(equal, &install_optimized); | 133 __ j(equal, &install_optimized); |
134 | 134 |
135 // Iterate through the rest of map backwards. edx holds an index as a Smi. | 135 // Iterate through the rest of map backwards. edx holds an index as a Smi. |
136 Label loop; | 136 Label loop; |
137 Label restore; | 137 Label restore; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 // Get the serialized scope info from the stack. | 254 // Get the serialized scope info from the stack. |
255 __ mov(ebx, Operand(esp, 2 * kPointerSize)); | 255 __ mov(ebx, Operand(esp, 2 * kPointerSize)); |
256 | 256 |
257 // Set up the object header. | 257 // Set up the object header. |
258 Factory* factory = masm->isolate()->factory(); | 258 Factory* factory = masm->isolate()->factory(); |
259 __ mov(FieldOperand(eax, HeapObject::kMapOffset), | 259 __ mov(FieldOperand(eax, HeapObject::kMapOffset), |
260 factory->block_context_map()); | 260 factory->block_context_map()); |
261 __ mov(FieldOperand(eax, Context::kLengthOffset), | 261 __ mov(FieldOperand(eax, Context::kLengthOffset), |
262 Immediate(Smi::FromInt(length))); | 262 Immediate(Smi::FromInt(length))); |
263 | 263 |
264 // If this block context is nested in the global context we get a smi | 264 // If this block context is nested in the native context we get a smi |
265 // sentinel instead of a function. The block context should get the | 265 // sentinel instead of a function. The block context should get the |
266 // canonical empty function of the global context as its closure which | 266 // canonical empty function of the native context as its closure which |
267 // we still have to look up. | 267 // we still have to look up. |
268 Label after_sentinel; | 268 Label after_sentinel; |
269 __ JumpIfNotSmi(ecx, &after_sentinel, Label::kNear); | 269 __ JumpIfNotSmi(ecx, &after_sentinel, Label::kNear); |
270 if (FLAG_debug_code) { | 270 if (FLAG_debug_code) { |
271 const char* message = "Expected 0 as a Smi sentinel"; | 271 const char* message = "Expected 0 as a Smi sentinel"; |
272 __ cmp(ecx, 0); | 272 __ cmp(ecx, 0); |
273 __ Assert(equal, message); | 273 __ Assert(equal, message); |
274 } | 274 } |
275 __ mov(ecx, GlobalObjectOperand()); | 275 __ mov(ecx, GlobalObjectOperand()); |
276 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset)); | 276 __ mov(ecx, FieldOperand(ecx, GlobalObject::kNativeContextOffset)); |
277 __ mov(ecx, ContextOperand(ecx, Context::CLOSURE_INDEX)); | 277 __ mov(ecx, ContextOperand(ecx, Context::CLOSURE_INDEX)); |
278 __ bind(&after_sentinel); | 278 __ bind(&after_sentinel); |
279 | 279 |
280 // Set up the fixed slots. | 280 // Set up the fixed slots. |
281 __ mov(ContextOperand(eax, Context::CLOSURE_INDEX), ecx); | 281 __ mov(ContextOperand(eax, Context::CLOSURE_INDEX), ecx); |
282 __ mov(ContextOperand(eax, Context::PREVIOUS_INDEX), esi); | 282 __ mov(ContextOperand(eax, Context::PREVIOUS_INDEX), esi); |
283 __ mov(ContextOperand(eax, Context::EXTENSION_INDEX), ebx); | 283 __ mov(ContextOperand(eax, Context::EXTENSION_INDEX), ebx); |
284 | 284 |
285 // Copy the global object from the previous context. | 285 // Copy the global object from the previous context. |
286 __ mov(ebx, ContextOperand(esi, Context::GLOBAL_INDEX)); | 286 __ mov(ebx, ContextOperand(esi, Context::GLOBAL_INDEX)); |
(...skipping 3143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3430 __ AllocateInNewSpace(ebx, eax, edx, edi, &runtime, TAG_OBJECT); | 3430 __ AllocateInNewSpace(ebx, eax, edx, edi, &runtime, TAG_OBJECT); |
3431 | 3431 |
3432 // eax = address of new object(s) (tagged) | 3432 // eax = address of new object(s) (tagged) |
3433 // ecx = argument count (tagged) | 3433 // ecx = argument count (tagged) |
3434 // esp[0] = mapped parameter count (tagged) | 3434 // esp[0] = mapped parameter count (tagged) |
3435 // esp[8] = parameter count (tagged) | 3435 // esp[8] = parameter count (tagged) |
3436 // esp[12] = address of receiver argument | 3436 // esp[12] = address of receiver argument |
3437 // Get the arguments boilerplate from the current (global) context into edi. | 3437 // Get the arguments boilerplate from the current (global) context into edi. |
3438 Label has_mapped_parameters, copy; | 3438 Label has_mapped_parameters, copy; |
3439 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 3439 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
3440 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); | 3440 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); |
3441 __ mov(ebx, Operand(esp, 0 * kPointerSize)); | 3441 __ mov(ebx, Operand(esp, 0 * kPointerSize)); |
3442 __ test(ebx, ebx); | 3442 __ test(ebx, ebx); |
3443 __ j(not_zero, &has_mapped_parameters, Label::kNear); | 3443 __ j(not_zero, &has_mapped_parameters, Label::kNear); |
3444 __ mov(edi, Operand(edi, | 3444 __ mov(edi, Operand(edi, |
3445 Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX))); | 3445 Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX))); |
3446 __ jmp(©, Label::kNear); | 3446 __ jmp(©, Label::kNear); |
3447 | 3447 |
3448 __ bind(&has_mapped_parameters); | 3448 __ bind(&has_mapped_parameters); |
3449 __ mov(edi, Operand(edi, | 3449 __ mov(edi, Operand(edi, |
3450 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX))); | 3450 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX))); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3622 __ j(zero, &add_arguments_object, Label::kNear); | 3622 __ j(zero, &add_arguments_object, Label::kNear); |
3623 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); | 3623 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); |
3624 __ bind(&add_arguments_object); | 3624 __ bind(&add_arguments_object); |
3625 __ add(ecx, Immediate(Heap::kArgumentsObjectSizeStrict)); | 3625 __ add(ecx, Immediate(Heap::kArgumentsObjectSizeStrict)); |
3626 | 3626 |
3627 // Do the allocation of both objects in one go. | 3627 // Do the allocation of both objects in one go. |
3628 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); | 3628 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); |
3629 | 3629 |
3630 // Get the arguments boilerplate from the current (global) context. | 3630 // Get the arguments boilerplate from the current (global) context. |
3631 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 3631 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
3632 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); | 3632 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); |
3633 const int offset = | 3633 const int offset = |
3634 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX); | 3634 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX); |
3635 __ mov(edi, Operand(edi, offset)); | 3635 __ mov(edi, Operand(edi, offset)); |
3636 | 3636 |
3637 // Copy the JS object part. | 3637 // Copy the JS object part. |
3638 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 3638 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { |
3639 __ mov(ebx, FieldOperand(edi, i)); | 3639 __ mov(ebx, FieldOperand(edi, i)); |
3640 __ mov(FieldOperand(eax, i), ebx); | 3640 __ mov(FieldOperand(eax, i), ebx); |
3641 } | 3641 } |
3642 | 3642 |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4139 // eax: Start of allocated area, object-tagged. | 4139 // eax: Start of allocated area, object-tagged. |
4140 | 4140 |
4141 // Set JSArray map to global.regexp_result_map(). | 4141 // Set JSArray map to global.regexp_result_map(). |
4142 // Set empty properties FixedArray. | 4142 // Set empty properties FixedArray. |
4143 // Set elements to point to FixedArray allocated right after the JSArray. | 4143 // Set elements to point to FixedArray allocated right after the JSArray. |
4144 // Interleave operations for better latency. | 4144 // Interleave operations for better latency. |
4145 __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX)); | 4145 __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX)); |
4146 Factory* factory = masm->isolate()->factory(); | 4146 Factory* factory = masm->isolate()->factory(); |
4147 __ mov(ecx, Immediate(factory->empty_fixed_array())); | 4147 __ mov(ecx, Immediate(factory->empty_fixed_array())); |
4148 __ lea(ebx, Operand(eax, JSRegExpResult::kSize)); | 4148 __ lea(ebx, Operand(eax, JSRegExpResult::kSize)); |
4149 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset)); | 4149 __ mov(edx, FieldOperand(edx, GlobalObject::kNativeContextOffset)); |
4150 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx); | 4150 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx); |
4151 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx); | 4151 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx); |
4152 __ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX)); | 4152 __ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX)); |
4153 __ mov(FieldOperand(eax, HeapObject::kMapOffset), edx); | 4153 __ mov(FieldOperand(eax, HeapObject::kMapOffset), edx); |
4154 | 4154 |
4155 // Set input, index and length fields from arguments. | 4155 // Set input, index and length fields from arguments. |
4156 __ mov(ecx, Operand(esp, kPointerSize * 1)); | 4156 __ mov(ecx, Operand(esp, kPointerSize * 1)); |
4157 __ mov(FieldOperand(eax, JSRegExpResult::kInputOffset), ecx); | 4157 __ mov(FieldOperand(eax, JSRegExpResult::kInputOffset), ecx); |
4158 __ mov(ecx, Operand(esp, kPointerSize * 2)); | 4158 __ mov(ecx, Operand(esp, kPointerSize * 2)); |
4159 __ mov(FieldOperand(eax, JSRegExpResult::kIndexOffset), ecx); | 4159 __ mov(FieldOperand(eax, JSRegExpResult::kIndexOffset), ecx); |
(...skipping 3344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7504 // Restore ecx. | 7504 // Restore ecx. |
7505 __ pop(ecx); | 7505 __ pop(ecx); |
7506 __ ret(0); | 7506 __ ret(0); |
7507 } | 7507 } |
7508 | 7508 |
7509 #undef __ | 7509 #undef __ |
7510 | 7510 |
7511 } } // namespace v8::internal | 7511 } } // namespace v8::internal |
7512 | 7512 |
7513 #endif // V8_TARGET_ARCH_IA32 | 7513 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |